﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CompanySearch.Library.Repository;
using MongoDB.Driver;
using MongoDB.Driver.Linq;

namespace CompanySearch.Library.Mongo
{
    public class MongoRepository : IRepository
    {

        private MongoClient _client = null;
        private readonly MongoDatabase _clientMongoDb = null;

        public MongoRepository(string connectionString)
        {
            var dbConnectionString = MongoUrl.Create(connectionString);

            if (string.IsNullOrWhiteSpace(dbConnectionString.DatabaseName))
            {
                throw new ArgumentException("No database specified in the connection string!");
            }

            _client = new MongoClient(dbConnectionString);
            var server = _client.GetServer();
            _clientMongoDb = server.GetDatabase(dbConnectionString.DatabaseName);
        }


        public List<Company> GetCompanyByStartsWith(string textToMatch,int skip, int take)
        {
            var dbCollection = this._clientMongoDb.GetCollection<Company>(typeof(Company).Name);
            var dbQueriableComany = dbCollection.AsQueryable<Company>();


            var startsWithRegex = new Regex(string.Format("^{0}.*", Regex.Escape(textToMatch)));

            var query = from c in dbQueriableComany
                        where startsWithRegex.IsMatch(c.Name)
                        orderby c.Name
                        select c;

            return query.Skip(skip).Take(take).ToList();
        }

        public List<Company> GetCompanyByContains(string textToMatch,int skip, int take)
        {
            //todo valide page/pagesize
            var dbCollection = this._clientMongoDb.GetCollection<Company>(typeof(Company).Name);
            var dbQueriableComany = dbCollection.AsQueryable<Company>();

            var containsNotStartingRegex = new Regex(string.Format("^(?!{0}).*{0}.*", Regex.Escape(textToMatch)));

            var queryContainsNoStart = from c in dbQueriableComany
                                       where containsNotStartingRegex.IsMatch(c.Name)
                                       orderby c.Name
                                       select c;

            return queryContainsNoStart.Skip(skip).Take(take).ToList();
        }

        public List<Guid> GetCompaniesByAttribute(string textToMatch)
        {
            var results = new List<Guid>();
            var res = from isin in this._clientMongoDb.GetCollection<Isin>("Isin").AsQueryable()
                      where isin.Value == textToMatch
                      select isin.CompanyId;
            results.AddRange(res);

            res =
                from item in this._clientMongoDb.GetCollection<Ticker>("Ticker").AsQueryable()
                where item.Value == textToMatch
                select item.CompanyId;
            
            results.AddRange(res);

            res =
                from item in this._clientMongoDb.GetCollection<Sedol>("Sedol").AsQueryable()
                where item.Value == textToMatch
                select item.CompanyId;
            results.AddRange(res);
            
            return results;
        }


        public List<Company> GetCompaniesByIds(List<Guid> ids)
        {
            var query = from item in this._clientMongoDb.GetCollection<Company>(typeof(Company).Name).AsQueryable()
                        where ids.Contains(item.Id)
                        select item;

            return query.ToList();
        }


    }



    public class Company
    {

        public Company()
        {
        }
        public List<string> Words { get; set; }

        public Guid Id { get; set; }
        
        public string Name {get;set;}

    }


    public class Ticker
    {
        public Guid Id { get; set; }

        public Guid CompanyId { get; set; }

        public string Value { get; set; }

        public string CompleteValue {get;set;}
    }

    public class Isin
    { 
        public Guid Id { get; set; }

        public Guid CompanyId { get; set; }
        public string Value { get; set;}
    }


    public class Sedol
    {
        public Guid CompanyId { get; set; }
        public Guid Id { get; set; }
        public string Value { get; set; }
    }
    
}
